package com.qire.common.utils;

import android.annotation.TargetApi;
import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.graphics.Rect;
import android.os.Build;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.DisplayCutout;
import android.view.ViewConfiguration;
import android.view.WindowManager;

import com.qire.common.SummerApp;
import com.qire.common.basic.StringUtil;

import java.lang.reflect.Method;

/**
 * 设备信息工具(包含屏幕宽度、高度、密度、设备厂商、状态栏、刘海高度等等)
 * */
public final class EquipmentInfoUtil {

    private static float density;               // 屏幕密度（0.75 / 1.0 / 1.5）
    private static int densityDpi;              // 屏幕密度dpi（120 / 160 / 240）
    private static int screenRealWidthPixels;   // 屏幕宽度(像素)
    private static int screenRealHeightPixels;  // 屏幕高度(像素)
    private static int screenWidthPixels;       // 屏幕宽度(像素)
    private static int screenHeightPixels;      // 屏幕高度(像素)
    private static int screenWidthDip;          // 屏幕宽度(dp)
    private static int screenHeightDip;         // 屏幕高度(dp)
    private static int statusBarHeight;         // 状态栏高度(像素)


    private static void measureRealMetrics(WindowManager windowManager) {
        Display display = windowManager.getDefaultDisplay();
        DisplayMetrics dm = new DisplayMetrics();
        try {
            Class<?> c = Class.forName("android.view.Display");
            Method method = c.getMethod("getRealMetrics", DisplayMetrics.class);
            method.invoke(display, dm);
            screenRealWidthPixels = dm.widthPixels;
            screenRealHeightPixels = dm.heightPixels;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private static void measureDefaultMetrics(WindowManager windowManager){
        DisplayMetrics dm   = new DisplayMetrics();
        windowManager.getDefaultDisplay().getMetrics(dm);

        density             = dm.density;
        densityDpi          = dm.densityDpi;
        screenWidthPixels   = dm.widthPixels;
        screenHeightPixels  = dm.heightPixels;
        // 屏幕宽度(dip)算法:屏幕宽度（像素）/屏幕密度
        screenWidthDip      = (int) (screenWidthPixels / density);
        screenHeightDip     = (int) (screenHeightPixels / density);
    }
    /**
     * 测量状态栏高度
     * */
    private static void measureStatusBarHeight(Application application) {
        int resourceId = application.getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            statusBarHeight = application.getResources().getDimensionPixelSize(resourceId);
        } else {
            statusBarHeight = 0;
        }
    }

    public static void init(Application application){

//        ScreenAdaptation.instance()
//                .setBaseWidth(390)  // 设计图的宽度 单位dp  必填.
//                .setBaseHeight(445)  // 设计图的高度 单位dp  必填.
//                .setBase(IdentificationEnum.WIDTH) //全局以哪个纬度开始适配 取值有IdentificationEnum.WIDTH,和IdentificationEnum.HEIGHT.
//                .setAutoScreenAdaptation(true) //开启全局适配
//                .create(application);

        WindowManager windowManager = (WindowManager) application.getSystemService(Context.WINDOW_SERVICE);
        measureRealMetrics(windowManager);
        measureDefaultMetrics(windowManager);
        measureStatusBarHeight(application);

        StringBuilder infoBuilder = new StringBuilder("EquipmentInfo:");
        infoBuilder.append("density=").append(density).append("|")
                .append("densityDpi=").append(densityDpi).append("|")
                .append("screenRealWidthPixels=").append(screenRealWidthPixels).append("|")
                .append("screenRealHeightPixels=").append(screenRealHeightPixels).append("|")
                .append("screenWidthPixels=").append(screenWidthPixels).append("|")
                .append("screenHeightPixels=").append(screenHeightPixels).append("|")
                .append("screenWidthDip=").append(screenWidthDip).append("|")
                .append("screenHeightDip=").append(screenHeightDip).append("|")
                .append("statusBarHeight=").append(statusBarHeight);
        Logger.i(infoBuilder.toString());
    }
  
    /** 
     * 根据手机的分辨率从 dp 的单位 转成为 px(像素) 
     */  
    public static int dip2px(float dpValue) {
        return (int) (dpValue * density + 0.5f);
    }  
  
    /** 
     * 根据手机的分辨率从 px(像素) 的单位 转成为 dp 
     */  
    public static int px2dip(float pxValue) {
        return (int) (pxValue / density + 0.5f);
    }

    /**
     * 获取屏幕的宽度(px(像素),真实)
     */
    public static int getScreenRealWidth() {
        return screenRealWidthPixels;
    }

    /**
     * 获取屏幕的高度(px(像素),真实)
     */
    public static int getScreenRealHeight() {
        return screenRealHeightPixels;
    }

    /**
     * 获取屏幕的宽度(px(像素),视口)
     */
    public static int getScreenWidth() {
        return screenWidthPixels;
    }

    /**
     * 获取屏幕的高度(px(像素)，视口)
     */
    public static int getScreenHeight() {
        return screenHeightPixels;
    }

    public static Rect getScreenRect(){
        return new Rect(0,0,screenWidthPixels,screenHeightPixels);
    }

    /**
     * 获取状态栏高度px像素
     * @return 状态栏的高度
     */
    public static int statusBarHeight() {
        return statusBarHeight;
    }

    /**
     * 在指定偏移量上获取状态栏高度px像素,
     * @param offsetDP 偏移量DP
     * @return statusBarHeight + offsetDP
     */
    public static int statusBarHeight(int offsetDP) {
        return statusBarHeight + dip2px(offsetDP);
    }

    /**
     * 获取手指脏区
     * @return
     */
    public static int getTouchSlopSquare() {
        final ViewConfiguration configuration = ViewConfiguration.get(SummerApp.summerApp());
        int touchSlop = configuration.getScaledTouchSlop();
        return touchSlop * touchSlop;
    }

    public static  DisplayMetrics getDisplayMetrics() {
        return SummerApp.summerApp().getResources().getDisplayMetrics();
    }

    //----------------------------------------------- 以上是屏幕和密度 以下是厂商及刘海 ----------------------------------------------

    public static int screenAdapter(float pxValue){
        if(density!=3f)
            pxValue = px2dip(pxValue)*3;
        return (int)pxValue;
    }

    /**
     * 自动判断手机厂商并且检查是否存在刘海并返回刘海高度
     * */
    public static int autoCheckHeightOfBangs(Activity activity){
        switch (getDeviceBrand()){
            case DEVICE_BRAND_HUAWEI:
                if(hasNotchInScreenAtHuawei(activity))
                    return getNotchSizeAtHuawei(activity);
                return 0;
            case DEVICE_BRAND_OPPO:
                if(hasNotchInScreenAtOppo(activity))
                    return getNotchSizeAtOppo();
                return 0;
            case DEVICE_BRAND_VIVO:
                if(hasNotchInScreenAtVivo(activity))
                    return getNotchSizeAtVivo(activity);
                return 0;
            default:
                if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
                    return getNotchParams(activity);
                return 0;
        }
    }

    /**
     * 是否有刘海屏
     *
     * @return
     */
    public static boolean hasNotchInScreen(Activity activity) {

        // android  P 以上有标准 API 来判断是否有刘海屏
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            DisplayCutout displayCutout = activity.getWindow().getDecorView().getRootWindowInsets().getDisplayCutout();
            if (displayCutout != null) {
                // 说明有刘海屏
                return true;
            }
        } else {
            // 通过其他方式判断是否有刘海屏  目前官方提供有开发文档的就 小米，vivo，华为（荣耀），oppo
            String manufacturer = Build.MANUFACTURER;

            if (StringUtil.isEmpty(manufacturer)) {
                return false;
            } else if (manufacturer.equalsIgnoreCase("HUAWEI")) {
                return hasNotchInScreenAtHuawei(activity);
            } else if (manufacturer.equalsIgnoreCase("oppo")) {
                return hasNotchInScreenAtOppo(activity);
            } else if (manufacturer.equalsIgnoreCase("vivo")) {
                return hasNotchInScreenAtVivo(activity);
            } else {
                return false;
            }
        }
        return false;
    }

    @TargetApi(28)
    public static int getNotchParams(Activity activity) {
        DisplayCutout displayCutout = activity.getWindow().getDecorView().getRootWindowInsets().getDisplayCutout();
        if(displayCutout==null)
            return 0;
        return displayCutout.getSafeInsetTop();
//        Log.e("TAG", "安全区域距离屏幕左边的距离 SafeInsetLeft:" + displayCutout.getSafeInsetLeft());
//        Log.e("TAG", "安全区域距离屏幕右部的距离 SafeInsetRight:" + displayCutout.getSafeInsetRight());
//        Log.e("TAG", "安全区域距离屏幕顶部的距离 SafeInsetTop:" + displayCutout.getSafeInsetTop());
//        Log.e("TAG", "安全区域距离屏幕底部的距离 SafeInsetBottom:" + displayCutout.getSafeInsetBottom());
//
//        List<Rect> rects = displayCutout.getBoundingRects();
//        if (rects == null || rects.size() == 0) {
//            Log.e("TAG", "不是刘海屏");
//        } else {
//            Log.e("TAG", "刘海屏数量:" + rects.size());
//            for (Rect rect : rects) {
//                Log.e("TAG", "刘海屏区域：" + rect);
//            }
//        }
    }


    // region #huawei 测量刘海 start
    /**
     * 华为手机检查是否存在刘海
     * */
    public static boolean hasNotchInScreenAtHuawei(Context context) {
        boolean ret = false;
        try {
            ClassLoader cl = context.getClassLoader();
            Class<?> HwNotchSizeUtil = cl.loadClass("com.huawei.android.util.HwNotchSizeUtil");
            Method get = HwNotchSizeUtil.getMethod("hasNotchInScreen");
            ret = (Boolean) get.invoke(HwNotchSizeUtil);
            Log.d("NotchScreenUtil", "this Huawei device has notch in screen？"+ret);
        } catch (ClassNotFoundException e) {
            Log.e("NotchScreenUtil", "hasNotchInScreen ClassNotFoundException", e);
        } catch (NoSuchMethodException e) {
            Log.e("NotchScreenUtil", "hasNotchInScreen NoSuchMethodException", e);
        } catch (Exception e) {
            Log.e("NotchScreenUtil", "hasNotchInScreen Exception", e);
        }
        return ret;
    }
    /**
     * 华为手机获取刘海高度
     * */
    public static int getNotchSizeAtHuawei(Context context) {
        int[] ret = new int[] { 0, 0 };
        try {
            ClassLoader cl = context.getClassLoader();
            Class<?> HwNotchSizeUtil = cl.loadClass("com.huawei.android.util.HwNotchSizeUtil");
            Method get = HwNotchSizeUtil.getMethod("getNotchSize");
            ret = (int[]) get.invoke(HwNotchSizeUtil);

        } catch (ClassNotFoundException e) {
            Log.e("NotchScreenUtil", "getNotchSize ClassNotFoundException");
        } catch (NoSuchMethodException e) {
            Log.e("NotchScreenUtil", "getNotchSize NoSuchMethodException");
        } catch (Exception e) {
            Log.e("NotchScreenUtil", "getNotchSize Exception");
        }
        return ret[1];
    }
    // endregion #huawei 测量刘海 end

    // region #Oppo 测量刘海 start
    /**
     * Oppo手机检查是否存在刘海
     * */
    public static boolean hasNotchInScreenAtOppo(Context context) {
        boolean hasNotch = context.getPackageManager().hasSystemFeature("com.oppo.feature.screen.heteromorphism");
        Log.d("NotchScreenUtil", "this OPPO device has notch in screen？"+hasNotch);
        return hasNotch;
    }
    /**
     * Oppo手机获取刘海高度
     * */
    public static int getNotchSizeAtOppo() {
        return 80;
    }
    // endregion #Oppo 测量刘海 end

    // region #vivo 测量刘海 start
    public static final int NOTCH_IN_SCREEN_VOIO = 0x00000020;// 是否有凹槽
    public static final int ROUNDED_IN_SCREEN_VOIO = 0x00000008;// 是否有圆角

    /**
     * vivo手机检查是否存在刘海
     * */
    public static boolean hasNotchInScreenAtVivo(Context context) {
        boolean ret = false;
        try {
            ClassLoader cl = context.getClassLoader();
            Class<?> FtFeature = cl.loadClass("com.util.FtFeature");
            Method get = FtFeature.getMethod("isFeatureSupport", int.class);
            ret = (Boolean) get.invoke(FtFeature, NOTCH_IN_SCREEN_VOIO);
            Log.d("NotchScreenUtil", "this VIVO device has notch in screen？" + ret);
        } catch (ClassNotFoundException e) {
            Log.e("NotchScreenUtil", "hasNotchInScreen ClassNotFoundException", e);
        } catch (NoSuchMethodException e) {
            Log.e("NotchScreenUtil", "hasNotchInScreen NoSuchMethodException", e);
        } catch (Exception e) {
            Log.e("NotchScreenUtil", "hasNotchInScreen Exception", e);
        }
        return ret;
    }
    /**
     * vivo手机获取刘海高度
     * */
    public static int getNotchSizeAtVivo(Context context){
        return dip2px( 32);
    }
    // endregion #vivo 测量刘海 end

    // region #手机厂商
    public final static int DEVICE_BRAND_OPPO = 0x0001;
    public final static int DEVICE_BRAND_HUAWEI = 0x0002;
    public final static int DEVICE_BRAND_VIVO = 0x0003;
    /**
     * 获取手机厂商
     * @return  手机厂商
     * */
    public static int getDeviceBrand() {
        String brand = android.os.Build.BRAND.trim().toUpperCase();
        if (brand.contains("HUAWEI")) {
            Log.d("device brand", "HUAWEI");
            return DEVICE_BRAND_HUAWEI;
        }else if (brand.contains("OPPO")) {
            Log.d("device brand", "OPPO");
            return DEVICE_BRAND_OPPO;
        }else if (brand.contains("VIVO")) {
            Log.d("device brand", "VIVO");
            return DEVICE_BRAND_VIVO;
        }
        return 0;
    }
    // endregion #手机厂商

}